package com.kexio.log.analytics.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import com.kexio.log.analytics.service.LogAnalyticsService;

/**
 * 日志分析服务实现
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
@ConditionalOnProperty(prefix = "kexio.log.analytics", name = "enabled", havingValue = "true")
public class LogAnalyticsServiceImpl implements LogAnalyticsService {
    
    private static final Logger logger = LoggerFactory.getLogger(LogAnalyticsServiceImpl.class);
    
    @Autowired
    private LogMetricsCollectorImpl metricsCollector;
    
    @Override
    public ErrorStatistics getErrorStatistics() {
        try {
            var overallMetrics = metricsCollector.getOverallMetrics();
            var exceptionMetrics = metricsCollector.getExceptionMetrics();
            
            Map<String, Long> errorTypes = exceptionMetrics.entrySet().stream()
                .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> entry.getValue().getTotalOccurrences()
                ));
            
            List<String> topErrors = exceptionMetrics.entrySet().stream()
                .sorted((e1, e2) -> Long.compare(e2.getValue().getTotalOccurrences(), e1.getValue().getTotalOccurrences()))
                .limit(10)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
            
            return new ErrorStatistics(
                overallMetrics.getTotalExceptions(),
                overallMetrics.getErrorRate(),
                errorTypes,
                topErrors,
                LocalDateTime.now()
            );
            
        } catch (Exception e) {
            logger.error("获取错误统计失败: {}", e.getMessage(), e);
            return new ErrorStatistics(0, 0.0, new HashMap<>(), new ArrayList<>(), LocalDateTime.now());
        }
    }
    
    @Override
    public PerformanceStatistics getPerformanceStatistics() {
        try {
            var requestMetrics = metricsCollector.getRequestMetrics();
            var performanceMetrics = metricsCollector.getPerformanceMetrics();
            
            double totalAvgTime = requestMetrics.values().stream()
                .mapToDouble(LogMetricsCollectorImpl.RequestMetrics::getAverageResponseTime)
                .average()
                .orElse(0.0);
            
            long slowRequests = requestMetrics.values().stream()
                .mapToLong(metrics -> metrics.getTotalRequests() - metrics.getSuccessfulRequests())
                .sum();
            
            long totalRequests = requestMetrics.values().stream()
                .mapToLong(LogMetricsCollectorImpl.RequestMetrics::getTotalRequests)
                .sum();
            
            double slowRequestRate = totalRequests > 0 ? (double) slowRequests / totalRequests : 0.0;
            
            Map<String, Double> endpointPerformance = requestMetrics.entrySet().stream()
                .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    entry -> entry.getValue().getAverageResponseTime()
                ));
            
            return new PerformanceStatistics(
                totalAvgTime,
                slowRequests,
                slowRequestRate,
                endpointPerformance,
                LocalDateTime.now()
            );
            
        } catch (Exception e) {
            logger.error("获取性能统计失败: {}", e.getMessage(), e);
            return new PerformanceStatistics(0.0, 0, 0.0, new HashMap<>(), LocalDateTime.now());
        }
    }
    
    @Override
    public UserBehaviorAnalysis getUserBehaviorAnalysis(String timeRange) {
        try {
            var userBehaviorMetrics = metricsCollector.getUserBehaviorMetrics();
            
            long activeUsers = userBehaviorMetrics.size();
            
            Map<String, Long> topActions = new HashMap<>();
            Map<String, Long> topResources = new HashMap<>();
            
            // 聚合所有用户的行为数据
            for (var userMetrics : userBehaviorMetrics.values()) {
                userMetrics.getActionCounts().forEach((action, count) ->
                    topActions.merge(action, count.get(), Long::sum));
                userMetrics.getResourceCounts().forEach((resource, count) ->
                    topResources.merge(resource, count.get(), Long::sum));
            }
            
            // 生成用户模式分析 (简化版)
            List<String> userPatterns = new ArrayList<>();
            if (activeUsers > 0) {
                userPatterns.add("活跃用户数: " + activeUsers);
                userPatterns.add("平均操作数: " + 
                    userBehaviorMetrics.values().stream()
                        .mapToLong(LogMetricsCollectorImpl.UserBehaviorMetrics::getTotalActions)
                        .average().orElse(0.0));
            }
            
            return new UserBehaviorAnalysis(
                activeUsers,
                topActions,
                topResources,
                userPatterns,
                LocalDateTime.now()
            );
            
        } catch (Exception e) {
            logger.error("获取用户行为分析失败: {}", e.getMessage(), e);
            return new UserBehaviorAnalysis(0, new HashMap<>(), new HashMap<>(), new ArrayList<>(), LocalDateTime.now());
        }
    }
    
    @Override
    public String generateReport(String reportType, String format) {
        try {
            StringBuilder report = new StringBuilder();
            
            if ("json".equalsIgnoreCase(format)) {
                report.append("{");
                report.append("\"reportType\":\"").append(reportType).append("\",");
                report.append("\"timestamp\":\"").append(LocalDateTime.now()).append("\",");
                
                switch (reportType.toLowerCase()) {
                    case "error":
                        ErrorStatistics errorStats = getErrorStatistics();
                        report.append("\"errorStatistics\":{");
                        report.append("\"totalErrors\":").append(errorStats.getTotalErrors()).append(",");
                        report.append("\"errorRate\":").append(errorStats.getErrorRate());
                        report.append("}");
                        break;
                    case "performance":
                        PerformanceStatistics perfStats = getPerformanceStatistics();
                        report.append("\"performanceStatistics\":{");
                        report.append("\"averageResponseTime\":").append(perfStats.getAverageResponseTime()).append(",");
                        report.append("\"slowRequests\":").append(perfStats.getSlowRequests());
                        report.append("}");
                        break;
                    default:
                        report.append("\"message\":\"Unknown report type\"");
                }
                
                report.append("}");
            } else {
                report.append("Log Analytics Report\n");
                report.append("Type: ").append(reportType).append("\n");
                report.append("Generated: ").append(LocalDateTime.now()).append("\n");
                report.append("Format not fully supported yet.\n");
            }
            
            return report.toString();
            
        } catch (Exception e) {
            logger.error("生成报告失败: {}", e.getMessage(), e);
            return "{\"error\":\"生成报告失败: " + e.getMessage() + "\"}";
        }
    }
    
    @Override
    public void resetAnalytics() {
        try {
            metricsCollector.resetMetrics();
            logger.info("日志分析数据已重置");
        } catch (Exception e) {
            logger.error("重置分析数据失败: {}", e.getMessage(), e);
        }
    }
}
